﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
using log4net;
using System.Web;
using System.Runtime.Remoting.Messaging;

namespace Mailer.Model
{
	public class SessionUtilities
	{
		static Configuration _config = null;
		static ISessionFactory factory = null;
		static int _leakchecker = 0;
	//	static ISession _nonwebsession = null;
		const string SessionKeyName = "nhibsess";

		private static ISession _innerCreateSession()
		{
			ISession ret = null;

			if (factory != null)
			{
				try
				{
					// Logger.Debug(typeof(SessionUtilities), "_innerCreateSession: Creating NHibernate session");

					ret = factory.OpenSession();
				}
				catch (Exception z)
				{
					Logger.Warn(typeof(SessionUtilities), z.ToString());
				}

				if (ret != null)
				{
					ret.FlushMode = FlushMode.Commit;

					_leakchecker++;
				}
			}

			return ret;
		}

		public static ISession BeginSession()
		{
			// Logger.Debug(typeof(SessionUtilities), "BeginSession, _leakchecker=" + _leakchecker + ", threadid=" + System.Threading.Thread.CurrentThread.ManagedThreadId);

			ISession ret = null;
			
			HttpContext ctx = HttpContext.Current;
			if (ctx != null)
			{
				if (ctx.Items[SessionKeyName] != null)
				{
					ret = (ISession)ctx.Items[SessionKeyName];
				}
				else
				{
					ret = _innerCreateSession();
					ctx.Items[SessionKeyName] = ret;
				}
			}
			else
			{
				object o = CallContext.GetData( SessionKeyName );
				if (o != null)
					ret = o as ISession;
				
				if( ret == null )
				{
					ret = _innerCreateSession();
					CallContext.SetData(SessionKeyName, ret);
				}

				// if (_nonwebsession == null)
				// 	_nonwebsession = _innerCreateSession();
				// ret = _nonwebsession;
				// ret = _innerCreateSession();
			}


			// CallContext.SetData(SessionKeyName, "");

			return ret;
		}

		public static void EndSession(ISession sess)
		{

			HttpContext ctx = HttpContext.Current;
			if (ctx != null)
			{
				// do nothing
			}
			else
			{/*
				if (sess != null)
				{
					_leakchecker--;
					sess.Flush();
					sess.Close();
				}*/
			}

			// Logger.Debug(typeof(SessionUtilities), "EndSession, _leakchecker=" + _leakchecker + ", threadid=" + System.Threading.Thread.CurrentThread.ManagedThreadId);
		}


		public static void Init()
		{
			Logger.Debug(typeof(SessionUtilities), "Init");

			if (_config == null)
			{
				Logger.Debug(typeof(SessionUtilities), "Init: Setting up NHibernate configuration");

				_config = new Configuration();
				_config.AddAssembly("Mailer.Model");
			}

			if (factory == null && _config != null)
			{
				Logger.Debug(typeof(SessionUtilities), "Init: Setting up NHibernate factory");

				factory = _config.BuildSessionFactory();
			}

//			_nonwebsession = null;
		}

		public static void BeginRequest()
		{
			// Logger.Debug(typeof(SessionUtilities), "BeginRequest, _leakchecker=" + _leakchecker);
			// _nonwebsession = null;

			// System.Threading.Thread.AllocateDataSlot(
		}

		public static void EndRequest()
		{
			HttpContext ctx = HttpContext.Current;
			if (ctx != null)
			{
				if (ctx.Items[SessionKeyName] != null)
				{
					ISession sess = (ISession)ctx.Items[SessionKeyName];
					if (sess != null)
					{
						// Logger.Debug(typeof(SessionUtilities), "EndRequest: Closing session");
						_leakchecker--;
						// sess.Flush();
						sess.Close();
					}
					ctx.Items.Remove(SessionKeyName);
				}
			}
			else
			{
				ISession sess = CallContext.GetData(SessionKeyName) as ISession;
				if (sess != null)
				{
					// Logger.Debug(typeof(SessionUtilities), "EndRequest: Closing session");
					_leakchecker--;
				//	sess.Flush();
					sess.Close();
					CallContext.SetData(SessionKeyName, null);
				} 
			}

			// Logger.Debug(typeof(SessionUtilities), "EndRequest, _leakchecker=" + _leakchecker);
		}
	}
}
